<?php
/**
 * Created by PhpStorm.
 * Script Name: BotFriend.php
 * Create: 2023/2/10 17:11
 * Description:
 * Author: fudaoji<fdj@kuryun.cn>
 */

namespace plugin\wechat\app\service;


use plugin\wechat\app\service\Bot as BotService;
use plugin\wechat\app\model\BotMember as MemberM;
use plugin\wechat\extend\WxBot\Driver\Cat;
use plugin\wechat\extend\WxBot\Driver\My;
use plugin\wechat\extend\WxBot\Driver\Vlw;
use plugin\wechat\extend\WxBot\Driver\Wxwork;

class BotFriend extends Common
{
    /**
     * 新增好友
     * @param array $params
     * Author: fudaoji<fdj@kuryun.cn>
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    static function addFriend($params = [])
    {
        $bot = $params['bot'];
        $insert = [
            'uin' => $bot['uin'],
            'nickname' => $params['nickname'],
            'username' => empty($params['username']) ? $params['wxid'] : $params['username'],
            'wxid' => $params['wxid'],
            'type' => BotService::FRIEND,
            'internal' => 1
        ];
        switch ($bot['protocol']){
            case BotService::PROTOCOL_WXWORK:
                $insert['internal'] = 2;
                break;
        }
        MemberM::create($insert);
        self::getMember($params['wxid'], $bot['uin'], true);
    }

    /**
     * 获取某个机器人的通讯录列表
     * @param string|null $uin
     * @param array $where
     * @return array|mixed|\think\db\Query|\think\Model|null
     */
    static function getWxidToNickname($uin = null, $where = []){
        if(is_null($uin)){
            $uin = \request()->botInfo['uin'];
        }
        $query = MemberM::where('uin', $uin);
        !empty($where) && $query = $query->where($where);
        return $query->column('nickname', 'wxid');
    }

    /**
     * 根据id获取数据库好友信息
     * @param string $id
     * @return array|mixed|\think\db\Query|\think\Model|null
     */
    static function getMemberById($id = ''){
        return MemberM::find($id);
    }

    /**
     * 获取数据库好友信息
     * @param string $wxid
     * @param string $uin
     * @param bool $refresh
     * @return array|mixed|\think\db\Query|\think\Model|null
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function getMember($wxid = '', $uin = null, $refresh = false){
        if(is_null($uin)){
            $uin = \request()->botInfo['uin'];
        }
        $key = wechat_cache_key(__FUNCTION__ . $uin . $wxid);
        $data = cache($key);
        if(empty($data) || $refresh){
            $data = MemberM::where('wxid', $wxid)
                ->where('uin', $uin)
                ->find();;
        }
        cache($key, $data);
        return $data;
    }

    /**
     * 拉取好友
     * @param $bot
     * @return int
     * @throws \Psr\SimpleCache\InvalidArgumentException
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * Author: fudaoji<fdj@kuryun.cn>
     */
    static function pullFriends($bot){
        /**
         * @var $client Cat|My
         */
        $client = BotService::getRobotClient($bot);
        $res = $client->getFriends([
            'data' => ['robot_wxid' => $bot['uin'], 'is_refresh' => 1, 'uuid' => $bot['uuid']]
        ]);
        $wxid_arr = [];
        $list = [];

        switch ($bot['protocol']){
            case Bot::PROTOCOL_XBOT:
                if($res['code'] && count($res['data'])){
                    $list = $res['data'];
                    $wxid_arr = [];
                    foreach ($list as $k => $v){
                        $nickname = filter_emoji($v['nickname']);
                        $remark_name = filter_emoji($v['remark']);
                        $username = $v['account'];
                        $headimgurl = $v['avatar'];
                        $wxid = $v['wxid'];
                        $wxid_arr[] = $wxid;
                        if($data = self::getMember($wxid, $bot['uin'])){
                            MemberM::update([
                                'id' => $data['id'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'headimgurl' => $headimgurl
                            ]);
                        }else{
                            MemberM::create([
                                'company_id' => $bot['company_id'],
                                'uin' => $bot['uin'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'wxid' => $wxid,
                                'type' => BotService::FRIEND,
                                'headimgurl' => $headimgurl
                            ]);
                        }
                    }
                }
                break;
            case Bot::PROTOCOL_CAT:
                if($res['code'] && count($res['data'])){
                    $list = $res['data'];
                    $wxid_arr = [];
                    foreach ($list as $k => $v){
                        $nickname = filter_emoji($v['nickname']);
                        $remark_name = filter_emoji($v['note']);
                        $username = $v['wx_num'];
                        $wxid = $v['wxid'];
                        $wxid_arr[] = $wxid;
                        if($data = self::getMember($wxid, $bot['uin'])){
                            MemberM::update([
                                'id' => $data['id'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username
                            ]);
                        }else{
                            MemberM::create([
                                'company_id' => $bot['company_id'],
                                'uin' => $bot['uin'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'wxid' => $wxid,
                                'type' => BotService::FRIEND
                            ]);
                        }
                    }
                }
                break;
            case Bot::PROTOCOL_MY:
                if($res['code'] && count($res['ReturnJson'])){
                    $list = $res['ReturnJson'];
                    foreach ($list as $k => $v){
                        $nickname = filter_emoji($v['nickname']);
                        $remark_name = filter_emoji($v['note']);
                        $username = $v['wx_num'];
                        $headimgurl = $v['avatar'];
                        $wxid = $v['wxid'];
                        $wxid_arr[] = $wxid;
                        if($data = self::getMember($wxid, $bot['uin'])){
                            MemberM::update([
                                'id' => $data['id'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'headimgurl' => $headimgurl,
                                'province' => $v['province'],
                                'city' => $v['city']
                            ]);
                        }else{
                            MemberM::create([
                                'company_id' => $bot['company_id'],
                                'uin' => $bot['uin'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'wxid' => $wxid,
                                'type' => BotService::FRIEND,
                                'headimgurl' => $headimgurl,
                                'province' => $v['province'],
                                'city' => $v['city']
                            ]);
                        }
                    }
                }
                break;
            default:
                if($res['code'] && count($res['data'])){
                    $list = $res['data'];
                    $wxid_arr = [];
                    foreach ($list as $k => $v){
                        $nickname = filter_emoji($v['nickname']);
                        $remark_name = filter_emoji($v['remark_name']);
                        $username = $v['username'];
                        $wxid = $v['wxid'];
                        $wxid_arr[] = $wxid;
                        if($data = self::getMember($wxid, $bot['uin'])){
                            MemberM::update([
                                'id' => $data['id'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username
                            ]);
                        }else{
                            MemberM::create([
                                'company_id' => $bot['company_id'],
                                'uin' => $bot['uin'],
                                'nickname' => $nickname,
                                'remark_name' => $remark_name,
                                'username' => $username,
                                'wxid' => $wxid,
                                'type' => Bot::FRIEND
                            ]);
                        }
                    }
                }
                break;
        }

        //删除无效好友
        MemberM::where('uin', $bot['uin'])
            ->where('type', BotService::FRIEND)
            ->where('wxid' , 'notin', $wxid_arr)
            ->delete();
        return count($list);
    }

    /**
     * 获取某个机器人的通讯录列表 {wxid: headimgurl, ...}
     * @param string|null $uin
     * @param array $where
     * @return array|mixed|\think\db\Query|\think\Model|null
     */
    static function getWxidToHead($uin = null, $where = []){
        if(is_null($uin)){
            $uin = \request()->botInfo['uin'];
        }
        $query = MemberM::where('uin', $uin)
            ->where('type', BotService::FRIEND);
        !empty($where) && $query = $query->where($where);
        return $query->column('headimgurl', 'wxid');
    }

    /**
     * 获取某个机器人的好友列表
     * @param string|null $uin
     * @param array $where
     * @return array|mixed|\think\db\Query|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    static function getFriendList($uin = null, $where = []){
        if(is_null($uin)){
            $uin = \request()->botInfo['uin'];
        }
        $query = MemberM::where('uin', $uin)
            ->where('type', BotService::FRIEND);
        !empty($where) && $query = $query->where($where);
        return $query->select();
    }
}